package main

import (
	"fmt"
	"io/ioutil"
	"net/http"
	"path"
	"sort"
	"strconv"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
)

const (
	PageSize = 50
)

type FileInfo struct {
	Name       string    `json:"name"`
	Dir        string    `json:"dir"`
	Type       string    `json:"type"`
	CreateTime time.Time `json:"createTime"`
	TimeFormat string    `json:"timeFormat"`
}

type FileInfoList []FileInfo

func (f FileInfoList) Len() int           { return len(f) }
func (f FileInfoList) Swap(i, j int)      { f[i], f[j] = f[j], f[i] }
func (f FileInfoList) Less(i, j int) bool { return f[i].CreateTime.After(f[j].CreateTime) }

func GetAllFile(pathname string) []FileInfo {
	fileList := []FileInfo{}
	rd, err := ioutil.ReadDir(pathname)
	if err != nil {
		fmt.Println(err)
	}
	for _, fi := range rd {
		totalPath := path.Join(pathname, fi.Name())
		if fi.IsDir() {
			fileList = append(fileList, FileInfo{
				Name:       fi.Name(),
				Dir:        totalPath,
				Type:       "dir",
				CreateTime: fi.ModTime(),
				TimeFormat: fi.ModTime().Format("2006-01-02 15:04:05"),
			})
		} else {
			// fmt.Printf("GetAllFile file %s\n", fi.Name())
			FileType := "unknow"
			if len(path.Ext(fi.Name())) > 0 {
				FileType = path.Ext(fi.Name())[1:]
			}
			fileList = append(fileList, FileInfo{
				Name:       fi.Name(),
				Dir:        totalPath,
				Type:       FileType,
				CreateTime: fi.ModTime(),
				TimeFormat: fi.ModTime().Format("2006-01-02 15:04:05"),
			})
		}
	}
	return fileList
}

func getFilePath(c *gin.Context) {
	filePath := c.Query("path")
	if !strings.HasSuffix(filePath, "/") {
		filePath = filePath + "/"
	}

	list := GetAllFile(filePath)
	fileList := FileInfoList{}
	dirList := FileInfoList{}

	for _, v := range list {
		if v.Type == "dir" {
			dirList = append(dirList, v)
		} else {
			fileList = append(fileList, v)
		}
	}
	sort.Sort(fileList)
	totalSize := fileList.Len()
	selectFileList := fileList[0:totalSize]
	if PageSize < totalSize {
		selectFileList = fileList[0:PageSize]
	}

	maxAge := totalSize / PageSize
	if totalSize > PageSize*maxAge {
		maxAge += 1
	}
	idxList := []int{}
	for i := 0; i < maxAge; i++ {
		idxList = append(idxList, i+1)
	}

	// c.JSON(200, gin.H{"path": path})
	c.HTML(http.StatusOK, "file.tmpl", gin.H{
		"totalSize":  totalSize,
		"idxList":    idxList,
		"fileList":   selectFileList,
		"dirList":    dirList,
		"currentDir": filePath,
	})
}

func freshFileList(c *gin.Context) {
	filePath := c.PostForm("path")
	if !strings.HasSuffix(filePath, "/") {
		filePath = filePath + "/"
	}

	page, err := strconv.Atoi(c.PostForm("page"))
	if err != nil {
		page = 1
	}

	list := GetAllFile(filePath)
	fileList := FileInfoList{}

	for _, v := range list {
		if v.Type != "dir" {
			fileList = append(fileList, v)
		}
	}
	sort.Sort(fileList)

	totalSize := fileList.Len()
	startIdx := (page - 1) * PageSize
	endIdx := page * PageSize
	if endIdx > totalSize {
		endIdx = totalSize
	}
	selectFileList := fileList[startIdx:endIdx]

	// c.JSON(200, gin.H{"path": path})
	c.JSON(http.StatusOK, selectFileList)
}

func BuildDirectionSystemMapping(engine *gin.Engine) {
	commandList := engine.Group("/getDirPath")
	commandList.GET("/", getFilePath)
	commandList.POST("/fresh", freshFileList)
}
